package com.wjm.api.ExecutorPackage;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Data:2022年07月28日
 * Author:wjm
 * Content: 线程池
 *
 *
 *  线程池概念：
 *         线程池其实是一个容纳多个线程的容器，其中的线程可以反复使用，省去了频繁创建线程对象的操作，无需反复创建线程
 *         而消耗过多的资源。
 *
 *  线程池的好处：
 *         1）降低资源消耗。通过反复利用已创建的线程，降低线程创建和销毁造成的消耗
 *         2）提高响应速度。当任务到达时不需要等到线程创建就能立即执行
 *         3）提高线程的可管理性。线程是稀缺资源，如果无限制的创建，不仅会消耗系统资源，还会降低系统稳定性，使用线程池
 *         可以进行统一分配，调优和监控
 *
 *  ExecutorService：
 *         ExecutorService是java提供用于管理线程池的类，我们使用ExecutorService来实现线程池。在java里线程池的
 *         顶级接口是 java.util.concurrent.Executor，但是严格意义上来说，Executor并不是一个线程池，而是一个执
 *         行线程的工具，真正的线程池接口是 java.util.concurrent.ExecutorService
 *
 *  线程池的主要作用：
 *         1）控制线程数量
 *         2）重用线程
 *
 *  线程池的实现策略：
 *        1）Executors.newFixedThreadPool(int nThreads)
 *                创建一个可重用固定线程集合的线程池，以共享无界队列的方式来运行这些线程
 *        2）Executors.newCachedThreadPool()
 *                创建一个可根据创建新线程的线程池，但是在以前构造的线程可用时将重用它们
 *        3）Executors.newScheduledThreadPool(int corePoolSize)
 *                创建一个线程池，它可安排在给定时延后运行命令或者定期的执行
 *        4）Executors.newSingleThreadExecutor()
 *                创建一个使用单个worker线程的Executor，以无界队列的方式来运行该线程
 *
 *  线程池的使用：
 *        获得了一个线程池对象ExecutorService之后要怎么使用
 *                public Future<?> submit(Runnable task) 将任务task提交给线程池
 *                       Future接口：用来记录线程任务执行完毕后产生的结果
 *                shutdown方法:用于销毁线程池（不建议执行）
 *
 *  线程池的使用步骤：
 *        1）创建线程池对象
 *        2）创建Runnable接口之类对象。（task）
 *        3）提交Runnable接口子类对象。（submit）
 *        4）关闭线程池。（一般不做）
 *
 */
public class ExecutorDemo {
    public static void main(String[] args) {
        //创建线程池对象,线程数量为5
        ExecutorService service = Executors.newFixedThreadPool(5);

        //创建Runnable接口之类对象
        Task task = new Task();

        //提交Runnable接口子类对象
        //将任务提交给了线程池，线程池通过自身的调度机制和挑选策略进行任务分配，
        // 任务执行之后线程是不会被销毁的，而是归还给了线程池，达到重用的目的
        service.submit(task);
        service.submit(task);
        service.submit(task);

        //销毁线程池
        service.shutdown();

    }
}
class Task implements Runnable{
    @Override
    public void run() {
        System.out.println("我要学驾照");
        System.out.println(Thread.currentThread().getName()+"教练教我技术");
        System.out.println("驾照拿到了");
    }
}